using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Diagnostics;
using Utils;
using WPFBPMN;
namespace CustomControls
{
    /// <summary>
    /// Interaction logic for BPMNCanvas.xaml
    /// </summary>

    public partial class BPMNCanvas : Canvas, IDragContainer
    {
        StartMouseDownInformation startMouseDownInformation;
        IDraggableContent currentWorkingElement = null;
        IDraggableContent currentSelectedElement = null;
        BPMNContainer currentContainer = null;
        IDragContainer bpmnParent;

        public new double Width
        {
            get
            {
                return base.Width;
            }
            set
            {
                base.Width = value;
                Debug.WriteLine("new width was set");
            }
        }


        public IDragContainer BPMNParent
        {
            get
            {
                return bpmnParent;
            }
            set
            {
                bpmnParent = value;
            }
        }
        public BPMNCanvas(IDragContainer bpmnParent)
        {
            this.bpmnParent = bpmnParent;
            InitializeComponent();
        }
        protected override void OnMouseEnter(MouseEventArgs e)
        {
            if (Mouse.LeftButton == MouseButtonState.Released)
            {
                currentWorkingElement = null;
            }
        }
        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            SendEventOnlyToTheParent(e);
            switch (WindowMain.MouseState)
            {
                case eMouseState.Drawing:
                    {

                        if (bpmnParent == null)
                        {
                            //building a new pool
                            if (WindowMain.DrawingToBuild != string.Empty)
                            {
                                BPMNShape drawing = BPMNShape.CreateDrawingByCommand(WindowMain.DrawingToBuild, this);
                                drawing.InitializeShape();
                                Canvas.SetLeft(drawing, e.GetPosition(this).X - drawing.Width / 2);
                                Canvas.SetTop(drawing, e.GetPosition(this).Y - drawing.Height / 2);

                                Canvas.SetLeft(drawing, 0);
                                if (Children.Count > 0)
                                {
                                    Control previousPool = Children[Children.Count - 1] as Control;
                                    Canvas.SetTop(drawing, Canvas.GetTop(previousPool) + previousPool.Height + 10);
                                }
                                else
                                {
                                    Canvas.SetTop(drawing, 0);
                                }
                                Children.Add(drawing);
                      
                            }
                            return;
                        }
                        BPMNContainer container = bpmnParent as BPMNContainer;
                        if (container == null | container.ContainerType == eContainerType.TopLevel | container.ContainerType == eContainerType.Pool)
                        {
                            return;
                        }
                        if (WindowMain.DrawingToBuild != string.Empty)
                        {
                            BPMNShape drawing = BPMNShape.CreateDrawingByCommand(WindowMain.DrawingToBuild, this);
                            drawing.InitializeShape();
                            Canvas.SetLeft(drawing, e.GetPosition(this).X - drawing.Width / 2);
                            Canvas.SetTop(drawing, e.GetPosition(this).Y - drawing.Height / 2);
                            Children.Add(drawing);

                            MoveWithReposition(drawing);
                        }
                    }
                    break;
                case eMouseState.Resizing:
                    if (currentWorkingElement != null)
                    {
                        startMouseDownInformation = new StartMouseDownInformation();
                        startMouseDownInformation.StartPoint = e.GetPosition(this);
                        startMouseDownInformation.Height = currentWorkingElement.DWHeight;
                        startMouseDownInformation.Width = currentWorkingElement.DWWidth;
                    }
                    break;
            }
        }
        protected override void OnMouseUp(MouseButtonEventArgs e)
        {

            SendEventOnlyToTheParent(e);
            currentWorkingElement = null;
        }
        protected void SendEventOnlyToTheParent(MouseEventArgs e)
        {
            if (!e.Handled)
            {
                e.Handled = true;
                if (bpmnParent != null)
                {
                    BPMNCanvas bpmnCanvas = (bpmnParent as BPMNCanvas);
                    if (bpmnCanvas != null)
                    {
                        bpmnCanvas.OnMouseMove(e);
                    }
                }
            }
        }


        protected void MoveWithReposition(IDraggableContent drawing)
        {
            double _left = Mouse.GetPosition(this).X - drawing.Offset.X;
            double _top = Mouse.GetPosition(this).Y - drawing.Offset.Y;
            double maxLeft = Width - drawing.DWWidth;
            double maxTop = Height - drawing.DWHeight;
            if (_left < 0)
            {
                _left = 0;
            }
            if (_top < 0)
            {
                _top = 0;
            }
            if (_left > maxLeft)
            {
                _left = maxLeft;
            }
            if (_top > maxTop)
            {
                _top = maxTop;
            }
            drawing.MoveTo(_left, _top);
            (drawing as BPMNShape).UpdateConnectingPoints();
            (drawing as BPMNShape).UpdateConnectedObjects();
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {

            SendEventOnlyToTheParent(e);
            switch (WindowMain.MouseState)
            {
                case eMouseState.Moving:
                    {
                        if (currentWorkingElement != null)
                        {
                            MoveWithReposition(currentWorkingElement);
                        }
                    }
                    break;
                case eMouseState.Resizing:
                    {
                        if (currentWorkingElement != null)
                        {
                            double _width = startMouseDownInformation.Width + Mouse.GetPosition(this).X - startMouseDownInformation.StartPoint.X;
                            double _height = startMouseDownInformation.Height + Mouse.GetPosition(this).Y - startMouseDownInformation.StartPoint.Y;
                            if ((currentWorkingElement as BPMNShape).LockSizeRatio)
                            {
                                if (_width < _height)
                                {
                                    _width = _height;
                                }
                                else
                                {
                                    _height = _width;
                                }
                            }
                            currentWorkingElement.ResizeTo(_width, _height);
                        }
                    }
                    break;
            }

        }

        #region IDragCanvas Members


        public IDraggableContent CurrentWorkingElement
        {
            get
            {
                return currentWorkingElement;
            }
            set
            {
                currentWorkingElement = value;
            }
        }

        public IDraggableContent CurrentSelectedElement
        {
            get
            {
                return currentSelectedElement;
            }
            set
            {
                currentSelectedElement = value;
            }
        }
        public StartMouseDownInformation StartInfo
        {
            get { return startMouseDownInformation; }
            set
            {
            }

        }
        #endregion




        #region IContainerHolder Members

        public BPMNContainer CurrentContainer
        {
            get
            {
                return currentContainer;
            }
            set
            {
                currentContainer = value;
            }
        }

        #endregion
    }
}